package com.wf.chatManagement.service.local.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wf.apicommons.entity.MessageBoard.LeavingAMessage;
import com.wf.apicommons.entity.MessageBoard.MqMessage;
import com.wf.apicommons.entity.chatManagement.ChatRecord;
import com.wf.apicommons.entity.chatManagement.FriendsRelationship;
import com.wf.apicommons.entity.chatManagement.GroupInfo;
import com.wf.apicommons.entity.userManagement.UserInformation;
import com.wf.apicommons.utils.CodeEnum;
import com.wf.apicommons.utils.CommonResult;
import com.wf.apicommons.utils.SnowflakeUtil;
import com.wf.chatManagement.mapper.ChatRecordMapper;
import com.wf.chatManagement.service.call.MessageBoardFeignService;
import com.wf.chatManagement.service.local.ChatRelatedService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: 聊天业务实现类
 */
@Service
@Slf4j
public class ChatRelatedServiceImpl implements ChatRelatedService {
    @Autowired
    private ChatRecordMapper crm;
    /**
     * feign 远程调用留言微服务
     */
    @Resource
    MessageBoardFeignService messageBoardFeignService;

    @Resource
    PushMessageService pushMessageService;
    /**
     * 创建一条好友验证关系数据
     * @param friendsRelationship
     * @return
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public CommonResult<String> createFriendVerification(FriendsRelationship friendsRelationship) {
            try{
                UserInformation userId = friendsRelationship.getUserId();
                UserInformation friendsId = friendsRelationship.getFriendsId();
                if(userId!=null&&friendsId!=null&&StrUtil.isNotBlank(userId.getID())&&StrUtil.isNotBlank(friendsId.getID())){
                    friendsRelationship.setID(SnowflakeUtil.getID());
                    friendsRelationship.setApplyWhetherAdopt(0);
                    friendsRelationship.setAddTime(new Date());
                    //添加好友申请
                    if(crm.insertFriendsRelationship(friendsRelationship)>0){

                        //创建一条留言
                        LeavingAMessage leavingAMessage=new LeavingAMessage();
                        leavingAMessage.setCommenterId(userId);
                        leavingAMessage.setRecipientId(friendsId);
                        leavingAMessage.setContent("邀请您成为好友");
                        leavingAMessage.setType(1);
                        leavingAMessage.setIsOperation(1);

                        //将留言推送至MQ
                        messageBoardFeignService.pushLeavingAMessageData(MqMessage.setMessageTypeAndData(leavingAMessage,MqMessage.MESSAGE_TYPE_PRIVATE_LETTER));
                    }
                    return  CommonResult.success("成功");
                }
            }catch (Exception exception){
                exception.printStackTrace();
                //.MySQLIntegrityConstraintViolationException 联合主键重复异常
                log.info("创建好友验证关系数据时发生错误：{}",exception.getMessage());
                throw exception;
            }


        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }


    /**
     * 添加一条群聊信息
     * @param groupInfo
     * @return
     */
    @Override
    @Transactional
   public CommonResult<String> addGroupInfo(GroupInfo groupInfo){
        if(StrUtil.isNotBlank(groupInfo.getGroupName())&&StrUtil.isNotBlank(groupInfo.getGroupAvatarImg())&&groupInfo.getCreateUserId()!=null&&StrUtil.isNotBlank(groupInfo.getCreateUserId().getID())){
            groupInfo.setID(SnowflakeUtil.getID());
            String groupNumber= SnowflakeUtil.getID();
            groupInfo.setGroupNumber(groupNumber);
            groupInfo.setCreateTime(new Date());
            //添加群聊信息
            crm.insertGroupInfo(groupInfo);
            //添加映射关系
            Map<String,Object> param=new HashMap<>(2);
            param.put("userInformationId",groupInfo.getCreateUserId().getID());
            param.put("groupNumber",groupNumber);
            addUserGroupRelationship(param,true);
            return CommonResult.success("成功");
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }


    /**
     * 查询我的好友列表
     * @param param
     * @return
     */
    @Override
    public CommonResult<Page<Map<String,Object>>> queryMyFriendsList(Map<String,Object> param){
        Integer page=MapUtil.getInt(param,"page",1);
        Integer size=MapUtil.getInt(param,"size",1);
        if(StrUtil.isNotBlank(MapUtil.getStr(param,"userId"))&&page>0&&size>0){
            Page<Map<String,Object>> queryPage=new Page<>(page,size);

            return  CommonResult.success(crm.selectMyFriendsList(queryPage,param));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }

    /**
     * 查询我的加入的群聊列表
     * @param param
     * @return
     */
    @Override
    public CommonResult<Page<Map<String,Object>>>  queryGroupChatListIJoined(Map<String,Object> param){
        Integer page=MapUtil.getInt(param,"page",1);
        Integer size=MapUtil.getInt(param,"size",1);
        if(StrUtil.isNotBlank(MapUtil.getStr(param,"userId"))&&page>0&&size>0){
            Page<Map<String,Object>> queryPage=new Page<>(page,size);
            return  CommonResult.success(crm.selectGroupChatListIJoined(queryPage,param));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }

    /**
     * 查询我创建的群聊列表
     * @param param
     * @return
     */
    @Override
    public CommonResult<Page<Map<String,Object>>>  queryMyCreateGroupChatList (Map<String,Object> param){
        Integer page=MapUtil.getInt(param,"page",1);
        Integer size=MapUtil.getInt(param,"size",1);
        if(StrUtil.isNotBlank(MapUtil.getStr(param,"userId"))&&page>0&&size>0){
            Page<Map<String,Object>> queryPage=new Page<>(page,size);
            return  CommonResult.success(crm.selectMyCreateGroupChatList(queryPage,param));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }


    /**
     * 查询会话列表
     * @param param
     * @return
     */
    @Override
  public  CommonResult<Page<Map<String,Object>>> querySessionList(Map<String,Object> param){
        Integer page=MapUtil.getInt(param,"page",1);
        Integer size=MapUtil.getInt(param,"size",13);
        if(StrUtil.isNotBlank(MapUtil.getStr(param,"userId"))&&page>0&&size>0){
            Page<Map<String,Object>> queryPage=new Page<>(page,size);
            return  CommonResult.success(crm.selectSessionList(queryPage,param));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }

    /**
     * 查询聊天记录列表
     * @param param
     * @return
     */
    @Override
    public   CommonResult<Page<Map<String,Object>>> queryChatRecordList(Map<String,Object> param){
        Integer page=MapUtil.getInt(param,"page",1);
        Integer size=MapUtil.getInt(param,"size",10);
        Integer type=MapUtil.getInt(param,"type",0);

        if(type!=null&&StrUtil.isNotBlank(MapUtil.getStr(param,"senderId"))&&StrUtil.isNotBlank(MapUtil.getStr(param,"recipientId"))&&page>0&&size>0){
            Page<Map<String,Object>> queryPage=new Page<>(page,size);
            Page<Map<String, Object>> result=null;
            if(type==0){
                result = crm.selectChatRecordList(queryPage, param);
            }else if(type==1){
                result = crm.selectGroupChatRecordList(queryPage,param);
            }

            return  CommonResult.success(result);
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }


    /**
     * 新增聊天记录
     * @param chatRecord
     * @return
     */
    @Override
    public CommonResult<String> addNewChatRecord(ChatRecord chatRecord){

        if(crm.insertChatRecord(chatRecord)>0){
            return CommonResult.success("新增聊天记录成功");
        }
        return CommonResult.fail("新增聊天记录失败");
    }

    /**
     * 修改聊天记录读取状态
     * @param chatRecord
     * @return
     */
    @Override
    public CommonResult<String> updateChatRecordReadStatus(ChatRecord chatRecord) {
        if(chatRecord.getType()!=null&&StrUtil.isNotBlank(chatRecord.getSenderId().getID())&&StrUtil.isNotBlank(chatRecord.getRecipientId())){
           if(chatRecord.getType()==0){
               UpdateWrapper updateWrapper = new UpdateWrapper();
               updateWrapper.eq("sender_id", chatRecord.getRecipientId());
               updateWrapper.eq("recipient_id", chatRecord.getSenderId().getID());
               updateWrapper.set("read_status",1);
               if(crm.update(null, updateWrapper)>0){
                   return CommonResult.success("成功");
               }
           }else if(chatRecord.getType()==1){
               //修改未读数量的参数
               Map<String, Object> updateParam = new HashMap(3);
               //填充修改未读数量的参数
               updateParam.put("operation", 0);
               updateParam.put("userInformationId", chatRecord.getSenderId().getID());
               updateParam.put("groupInfoId", chatRecord.getRecipientId());
               //修改群聊消息未读数量
               if( crm.updateUnreadNumberOfGroupChatMessages(updateParam)>0){
                   return CommonResult.success("成功");
               }
           }


        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }


    /**
     * 添加用户与群聊的映射关系
     * @return
     */
    @Override
    @Transactional
    public  CommonResult<String> addUserGroupRelationship(Map<String,Object> param,boolean isItMe){

            String nickName = MapUtil.getStr(param, "nickName");
            String userInformationId = MapUtil.getStr(param, "userInformationId");
            String messageContent ="您已成功创建群聊";
            if(!isItMe){
                if(StrUtil.isNotBlank(nickName)){
                    messageContent ="大家好，我是".concat(nickName).concat("以后请多多关照~");
                }else {
                    return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
                }
            }


            if(StrUtil.isNotBlank(userInformationId)&&StrUtil.isNotBlank(MapUtil.getStr(param,"groupNumber"))){
                //查询群聊信息
                Map<String, Object> groupInfo = crm.selectGroupInfo(param);
                String groupInfoId = MapUtil.getStr(groupInfo, "ID");
                if(groupInfo==null||groupInfo.size()< 1||StrUtil.isBlank(groupInfoId)){
                    return CommonResult.fail(CodeEnum.RESOURCE_DOES_NOT_EXIST);
                }

                /**
                 * "messageType":"message_type_chat","jsonData":"{\"ID\":\"1561627460084985856\",\"senderId\":{\"ID\":\"1537739532242083840\",\"avatarLink\":\"https://img2.baidu.com/it/u=4244269751,4000533845&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500\",\"nickName\":\"张三\"},\"recipientId\":\"1560934704698138624\",\"messageContent\":\"嗯嗯\",\"sendTime\":1661155974776,\"readStatus\":0,\"type\":1,\"isInitializationContent\":0}"}
                 */
                param.put("ID",SnowflakeUtil.getID());
                param.put("joinTime",new Date());
                param.put("unreadQuantity",0);
                param.put("groupInfoId",groupInfoId);
                //插入用户与群信息的映射记录
                if(crm.insertUserGroupRelationship(param)>0){
                    //缓存映射关系
                    pushMessageService.setUserGroupRelationship(userInformationId,groupInfoId);

                    ChatRecord chatRecord=new ChatRecord();
                    UserInformation userInformation=new UserInformation();
                    userInformation.setID(userInformationId);
                    //将群聊名称和群聊头像暂时设置进去
                    userInformation.setNickName(MapUtil.getStr(groupInfo, "group_name"));
                    userInformation.setAvatarLink(MapUtil.getStr(groupInfo, "group_avatar_img"));

                    chatRecord.setSenderId(userInformation);
                    chatRecord.setRecipientId(groupInfoId);
                    chatRecord.setMessageContent(messageContent);
                    chatRecord.setType(1);
                    chatRecord.setIsInitializationContent(1);
                    chatRecord.setReadStatus(1);
                    if(!isItMe){
                        chatRecord.setIsInitializationContent(0);
                        chatRecord.setReadStatus(0);
                    }

                    //推送消息
                   pushMessageService.sendChatMessage(JSONUtil.toJsonStr(MqMessage.setMessageTypeAndData(chatRecord,MqMessage.MESSAGE_TYPE_CHAT)),false,true);

                    return CommonResult.success("成功");
                }
            }
            return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);


    }



    /**
     * 修改用户群聊消息未读数量
     * @param param
     */
    @Override
    public  CommonResult<String> updateUnreadNumberOfGroupChatMessages(Map<String,Object> param){
        if(StrUtil.isNotBlank(MapUtil.getStr(param,"operation"))&&StrUtil.isNotBlank(MapUtil.getStr(param,"userInformationId"))&&StrUtil.isNotBlank(MapUtil.getStr(param,"groupInfoId"))){
            crm.updateUnreadNumberOfGroupChatMessages(param);
            return CommonResult.success("成功");
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }



    /**
     * 查询聊天未读消息总数
     * @param userId
     * @return
     */
    @Override
    public   CommonResult<Map<String,Object>>  queryNumberOfChatUnreadMessages(String userId){
        if(StrUtil.isNotBlank(userId)){
            return CommonResult.success(crm.selectNumberOfChatUnreadMessages(userId));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }

    /**
     * 推送聊天消息
     * @param message
     * @return
     */
    @Override
    public CommonResult<Boolean> pushChatMessage(String message){
        if(StrUtil.isNotBlank(message)){

            return CommonResult.success(pushMessageService.sendChatMessage(message,false,false));
        }
        return CommonResult.fail(CodeEnum.ILLEGAL_PARAMETER);
    }

}
